using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace YouTubeDupe
{
    public partial class MainForm : Form
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }

        Thread displayThreadThread;
        ToolStripSeparator sep = new ToolStripSeparator();
        delegate void removeDelegate(object sender, YouTubeDupe.SessionChangedEventArgs e);
        delegate void setTextDelegate(ToolStripItem item, string text);
        System.Windows.Forms.Timer pauseTimer;

        /// <summary>
        /// Creates a new instance of the main form.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();
            Icon = Resources.Icon;
        }

        /// <summary>
        /// Starts all initial threads.
        /// </summary>
        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);

            BringToFront();

            YouTubeDupe.SessionPool.SessionAdded += new YouTubeDupe.SessionChangedEventHanlder(SessionPool_SessionAdded);
            YouTubeDupe.SessionPool.SessionRemoved += new YouTubeDupe.SessionChangedEventHanlder(SessionPool_SessionRemoved);

            displayThreadThread = new Thread(new ThreadStart(displayThread));
            displayThreadThread.Start();

            pauseTimer = new System.Windows.Forms.Timer();
            pauseTimer.Interval = 2000;
            pauseTimer.Tick += new EventHandler(pauseTimer_Tick);
            pauseTimer.Start();
        }

        /// <summary>
        /// Minimizes the window to the system tray.
        /// </summary>
        private void pauseTimer_Tick(object sender, EventArgs e)
        {
            Hide();
            pauseTimer.Stop();
        }

        /// <summary>
        /// Occurs when a new session is added to the session pool.
        /// </summary>
        private void SessionPool_SessionAdded(object sender, YouTubeDupe.SessionChangedEventArgs e)
        {
            if (YouTubeDupe.SessionPool.Count == 1)
            {
                contextMenu.Items.Insert(0, sep);
            }

            ToolStripMenuItem newSession = new ToolStripMenuItem("New session");
            newSession.Name = e.Session.GetHashCode().ToString();
            newSession.Tag = e.Session;
            contextMenu.Items.Insert(0, newSession);
        }

        /// <summary>
        /// Occurs when a session is removed from the session pool.
        /// </summary>
        private void SessionPool_SessionRemoved(object sender, YouTubeDupe.SessionChangedEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new removeDelegate(SessionPool_SessionRemoved), sender, e);
            }
            else
            {
                ToolStripItem item = contextMenu.Items.Find(e.Session.GetHashCode().ToString(), false)[0];
                contextMenu.Items.Remove(item);

                if (YouTubeDupe.SessionPool.Count == 0)
                {
                    contextMenu.Items.RemoveAt(0);
                }
            }
        }

        /// <summary>
        /// Creates a new session when the "New session" item is clicked.
        /// </summary>
        private void tsMenuNewSession_Click(object sender, EventArgs e)
        {
            YouTubeDupe.SessionPool.CreateSession();
        }

        /// <summary>
        /// Opens the session the user clicked on.
        /// </summary>
        private void contextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            YouTubeDupe.SessionController session = e.ClickedItem.Tag as YouTubeDupe.SessionController;
            if (session == null) return;
            System.Diagnostics.Process.Start(session.SessionURL);
        }

        /// <summary>
        /// Updates the context menu with the currently running sessions.
        /// </summary>
        private void displayThread()
        {
            while (true)
            {
                if (YouTubeDupe.SessionPool.Count > 0)
                {
                    List<YouTubeDupe.SessionController>.Enumerator e = YouTubeDupe.SessionPool.GetEnumerator();
                    while (e.MoveNext())
                    {
                        foreach (ToolStripItem item in contextMenu.Items)
                        {
                            if (item.Tag == null) continue;

                            if (item.Tag.Equals(e.Current))
                            {
                                setText(item, e.Current.StateString);
                            }
                        }
                    }
                }

                Thread.Sleep(5000);
            }
        }

        /// <summary>
        /// A thread safe method to update a tool strip item's text.
        /// </summary>
        /// <param name="item">The tool strip item.</param>
        /// <param name="text">The text to set.</param>
        private void setText(ToolStripItem item, string text)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new setTextDelegate(setText), item, text);
            }
            else
            {
                item.Text = text;
            }
        }

        /// <summary>
        /// Closes the progran.
        /// </summary>
        private void tsMenuClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        /// <summary>
        /// Occurs when the program is closing, ensures all sessions are stopped.
        /// </summary>
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);

            if (YouTubeDupe.SessionPool.Count > 0)
            {
                DialogResult result = MessageBox.Show("Are you sure you want to exit? All current sessions will become unresponsive.", "Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);

                if (result == DialogResult.Yes)
                {
                    YouTubeDupe.SessionPool.StopAll();
                    displayThreadThread.Abort();
                    e.Cancel = false;
                }
                else
                {
                    e.Cancel = true;
                }
            }
            else
            {
                YouTubeDupe.SessionPool.StopAll();
                displayThreadThread.Abort();
                e.Cancel = false;
            }
        }

        /// <summary>
        /// Opens the results folder.
        /// </summary>
        private void tsMenuOpenResults_Click(object sender, EventArgs e)
        {
            string resultsPath = AppDomain.CurrentDomain.BaseDirectory + "results\\";

            try
            {
                if (!System.IO.Directory.Exists(resultsPath))
                {
                    System.IO.Directory.CreateDirectory(resultsPath);
                }

                System.Diagnostics.Process.Start(resultsPath);
            }
            catch (Exception)
            {
                MessageBox.Show("An error occured while trying to create or access the results folder.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}